﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class ShutdownApp : Form
    {

        public ShutdownApp()
        {
            InitializeComponent();
            this.shutdownByTimeRbtn.Checked = true;
        }

        private void shutdownByTimeRbtn_CheckedChanged(object sender, EventArgs e)
        {
            disableProcess("clock", false, true);
            enableProcess("time", true, true);
        }

        private void disableProcess(String code, Boolean isIncludeRadioBtn, Boolean cleanText)
        {
            if (code.Equals("time"))
            {
                this.textHour1.ReadOnly = true;
                this.textMin1.ReadOnly = true;
                if (isIncludeRadioBtn)
                {
                    this.shutdownByTimeRbtn.Enabled = false;
                }
                if (cleanText)
                {
                    this.textHour1.Text = "";
                    this.textMin1.Text = "";
                }
            }
            if (code.Equals("clock"))
            {
                this.textHour2.ReadOnly = true;
                this.textMin2.ReadOnly = true;
                if (isIncludeRadioBtn)
                {
                    this.shutdownByClockRbtn.Enabled = false;
                }
                if (cleanText)
                {
                    this.textHour2.Text = "";
                    this.textMin2.Text = "";
                }
            }

        }

        private void shutdownByClockRbtn_CheckedChanged(object sender, EventArgs e)
        {
            disableProcess("time", false, true);
            enableProcess("clock", true, true);
        }

        private void enableProcess(String code, Boolean isIncludeRadioBtn, Boolean cleanText)
        {
            if (code.Equals("time"))
            {
                this.textHour1.ReadOnly = false;
                this.textMin1.ReadOnly = false;
                if (isIncludeRadioBtn)
                {
                    this.shutdownByTimeRbtn.Enabled = true;
                }
                if (cleanText)
                {
                    this.textHour1.Text = "";
                    this.textMin1.Text = "";
                }
            }
            if (code.Equals("clock"))
            {
                this.textHour2.ReadOnly = false;
                this.textMin2.ReadOnly = false;
                if (isIncludeRadioBtn)
                {
                    this.shutdownByClockRbtn.Enabled = true;
                }
                if (cleanText)
                {
                    this.textHour2.Text = "";
                    this.textMin2.Text = "";
                }
            }

        }

        private void textHour1_TextChanged(object sender, EventArgs e)
        {
            CommonUtils.hourNumValidate(this.textHour1);
        }

        private void textMin1_TextChanged(object sender, EventArgs e)
        {
            CommonUtils.minuteNumValidate(this.textMin1);
        }

        private void textHour2_TextChanged(object sender, EventArgs e)
        {
            CommonUtils.hourNumValidate(this.textHour2);
        }

        private void textMin2_TextChanged(object sender, EventArgs e)
        {
            CommonUtils.minuteNumValidate(this.textMin2);
        }

        private void cancleBtn_Click(object sender, EventArgs e)
        {
            this.cancleBtn.Visible = false;
            this.startBtn.Visible = true;
            this.shutdownByTime_flag = false;
            this.shutdownByClock_flag = false;
            if (shutdownByClockRbtn.Checked)
            {
                this.enableProcess("clock", true, false);
            }
            if (shutdownByTimeRbtn.Checked)
            {
                this.enableProcess("time", true, false);
            }
            this.tipsLabel.Text = "";
        }

        private void startBtn_Click(object sender, EventArgs e)
        {
            if (this.shutdownByTimeRbtn.Checked)
            {
                if (StringUtils.isBlank(this.textHour1.Text))
                {
                    MessageBox.Show("请输入时间值");
                    this.textHour1.Focus();
                    return;
                }
                if (StringUtils.isBlank(this.textMin1.Text))
                {
                    MessageBox.Show("请输入时间值");
                    this.textMin1.Focus();
                    return;
                }
                CommonUtils.numberValueHandle(this.textHour1, this.textMin1);
                this.shutdownByTimeThread = new Thread(shutdownByTime);
                shutdownByTimeThread.IsBackground = true;
                ShutdownTime time;
                time.hour = this.textHour1.Text;
                time.minute = this.textMin1.Text;
                this.shutdownByTime_flag = true;
                shutdownByTimeThread.Start(time);
                this.tipsLabel.Text = "电脑将于" + this.textHour1.Text + "时" + this.textMin1.Text + "分关闭。如需取消请点击取消";

            }
            if (this.shutdownByClockRbtn.Checked)
            {
                if (StringUtils.isBlank(this.textHour2.Text))
                {
                    MessageBox.Show("请输入时间值");
                    this.textHour2.Focus();
                    return;
                }
                if (StringUtils.isBlank(this.textMin2.Text))
                {
                    MessageBox.Show("请输入时间值");
                    this.textMin2.Focus();
                    return;
                }
                CommonUtils.numberValueHandle(this.textHour2, this.textMin2);
                this.shutdownByClockThread = new Thread(shuwdownByClock);
                this.shutdownByClockThread.IsBackground = true;
                int timer = int.Parse(this.textHour2.Text) * 60 * 60 * 1000 +
                    int.Parse(this.textMin2.Text) * 60 * 1000;
                this.shutdownByClock_flag = true;
                this.shutdownByClockThread.Start(timer);
            }
            disableProcess("time", false, false);
            disableProcess("clock", false, false);
            this.cancleBtn.Visible = true;
            this.startBtn.Visible = false;
            this.tipsLabel.Focus();
        }

        public void shuwdownByClock(Object obj)
        {
            int timer = (int)obj;
            while (timer > 0)
            {
                if (this.shutdownByClock_flag)
                {
                    Dictionary<String, int> countdownMap = CommonUtils.getCountdownMap(timer);
                    this.SetText("电脑将于" + countdownMap["hour"] + "小时" + countdownMap["minutes"] + "分钟"
                                    + countdownMap["seconds"] + "秒后关闭。如需取消请点取消按钮。");
                    timer = timer - 1000;
                    Thread.Sleep(1000);
                }
                else
                {
                    timer = 0;
                }

            }
            if (this.shutdownByClock_flag)
            {
                CommonUtils.shutdown();
            }
        }

        delegate void SetTextCallback(string text);

        public void shutdownByTime(Object obj)
        {
            ShutdownTime time = (ShutdownTime)obj;
            while (this.shutdownByTime_flag)
            {
                int currentHour = DateTime.Now.Hour;
                int currentMin = DateTime.Now.Minute;
                int shutdownHour = int.Parse(time.hour);
                int shutdownMin = int.Parse(time.minute);
                if (currentHour == shutdownHour && currentMin == shutdownMin)
                {
                    this.shutdownByTime_flag = false;
                    CommonUtils.shutdown();
                }
                else
                {
                    Thread.Sleep(25000);
                }
            }
        }

        private void shutdownApp_Load(object sender, EventArgs e)
        {

        }

        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.tipsLabel.InvokeRequired)
            {
                SetTextCallback cb = new SetTextCallback(SetText);
                this.Invoke(cb, new object[] { text });
            }
            else
            {
                this.tipsLabel.Text = text;
            }
        }
    }

    struct ShutdownTime
    {
        public string hour;
        public string minute;
    };
}
